#include "minisoundmanager.h"

#include "Core/Shared/Audio/SoundMixer.h"
#include "Core/Shared/EmuSettings.h"
#include "Core/Shared/Emulator.h"
#include "Core/Shared/MessageManager.h"

MiniSoundManager::MiniSoundManager(Emulator *emu)
    : m_emulator(emu)
{
    emu->GetSoundMixer()->RegisterAudioDevice(this);

    config = ma_device_config_init(ma_device_type_playback);
    config.playback.format = ma_format_s16;
    config.playback.channels = 2; // Stereo
    config.sampleRate = 44100;
    config.dataCallback = [](ma_device *device, void *output, const void *input, ma_uint32 frameCount) {
        auto *self = reinterpret_cast<MiniSoundManager *>(device->pUserData);

        ma_uint32 framesRead = frameCount;
        void *pReadBuffer = nullptr;
        ma_result result = ma_pcm_rb_acquire_read(&self->m_ringBuffer, &framesRead, &pReadBuffer);
        if (result == MA_SUCCESS && framesRead > 0) {
            memcpy(output, pReadBuffer, framesRead * 2 * sizeof(int16_t));
            ma_pcm_rb_commit_read(&self->m_ringBuffer, framesRead);
        }

        // 如果缓冲区不足，用0填充（静音）
        if (framesRead < frameCount) {
            int16_t *out = (int16_t *)output;
            memset(out + framesRead * 2, 0, (frameCount - framesRead) * 2 * sizeof(int16_t));
            self->_bufferUnderrunEventCount++;
        }
    };
    config.pUserData = this;

    // 初始化环形缓冲区，1秒容量
    if (ma_pcm_rb_init(config.playback.format, config.playback.channels, 44100, NULL, NULL, &m_ringBuffer) != MA_SUCCESS) {
        throw std::runtime_error("Failed to initialize ring buffer.");
    }

    if (ma_device_init(NULL, &config, &m_device) != MA_SUCCESS) {
        throw std::runtime_error("Failed to initialize audio device.");
    }

    if (ma_device_start(&m_device) != MA_SUCCESS) {
        throw std::runtime_error("Failed to start audio device.");
    }
}

MiniSoundManager::~MiniSoundManager()
{
    ma_device_stop(&m_device);
    ma_device_uninit(&m_device);
    ma_pcm_rb_uninit(&m_ringBuffer);
}

void MiniSoundManager::PlayBuffer(int16_t *soundBuffer, uint32_t bufferSize, uint32_t sampleRate, bool isStereo)
{
    if (config.sampleRate != sampleRate || config.playback.channels != (isStereo ? 2 : 1)) {
        // 如果采样率不匹配，重新配置设备
        ma_device_stop(&m_device);
        ma_device_uninit(&m_device);
        ma_pcm_rb_uninit(&m_ringBuffer);

        config.sampleRate = sampleRate;
        config.playback.channels = isStereo ? 2 : 1;

        if (ma_pcm_rb_init(config.playback.format, config.playback.channels, sampleRate, NULL, NULL, &m_ringBuffer) != MA_SUCCESS) {
            throw std::runtime_error("Failed to reinitialize ring buffer with new sample rate.");
        }

        if (ma_device_init(NULL, &config, &m_device) != MA_SUCCESS) {
            throw std::runtime_error("Failed to reinitialize audio device with new sample rate.");
        }
        if (ma_device_start(&m_device) != MA_SUCCESS) {
            throw std::runtime_error("Failed to restart audio device with new sample rate.");
        }
    }

    ma_uint32 framesToWrite = bufferSize;
    void *pWriteBuffer = nullptr;
    ma_result result = ma_pcm_rb_acquire_write(&m_ringBuffer, &framesToWrite, &pWriteBuffer);
    if (result == MA_SUCCESS && framesToWrite > 0) {
        memcpy(pWriteBuffer, soundBuffer, framesToWrite * 2 * sizeof(int16_t));
        ma_pcm_rb_commit_write(&m_ringBuffer, framesToWrite);
    }
}

void MiniSoundManager::Stop()
{
    ma_pcm_rb_reset(&m_ringBuffer);
}

void MiniSoundManager::Pause()
{
    Stop();
}

void MiniSoundManager::ProcessEndOfFrame()
{
}

string MiniSoundManager::GetAvailableDevices()
{
    return "Default Device";
}

void MiniSoundManager::SetAudioDevice(string deviceName)
{
    (void)deviceName;
}

AudioStatistics MiniSoundManager::GetStatistics()
{
    AudioStatistics stats;
    stats.AverageLatency = _averageLatency;
    stats.BufferUnderrunEventCount = _bufferUnderrunEventCount;
    stats.BufferSize = _bufferSize;
    return stats;
}
